]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
altTab: Avoid allocation cycle when showing CyclerHighlight
authorSebastian Keller <skeller@gnome.org>
Tue, 11 May 2021 14:43:37 +0000 (16:43 +0200)
committerSebastian Keller <skeller@gnome.org>
Tue, 11 May 2021 15:36:29 +0000 (17:36 +0200)
CyclerHighlight was showing and resizing one of its child widgets when
its own allocation was changed, queuing another relayout, resulting in
allocation cycle warnings. Avoid this by updating the size of the
highlight when the frame rect of window has changes rather than the size
of the CyclerHighlight actor itself.

Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4167
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1842>

js/ui/altTab.js

index bc8b17fac377d11295a490706ad6b372b032ceee..6af9380edc4bde532fb310aa5185907f79727014 100644 (file)
@@ -402,6 +402,7 @@ class CyclerHighlight extends St.Widget {
     _init() {
         super._init({ layout_manager: new Clutter.BinLayout() });
         this._window = null;
+        this._sizeChangedId = 0;
 
         this._clone = new Clutter.Clone();
         this.add_actor(this._clone);
@@ -415,7 +416,6 @@ class CyclerHighlight extends St.Widget {
 
         this.add_constraint(constraint);
 
-        this.connect('notify::allocation', this._onAllocationChanged.bind(this));
         this.connect('destroy', this._onDestroy.bind(this));
     }
 
@@ -423,6 +423,9 @@ class CyclerHighlight extends St.Widget {
         if (this._window == w)
             return;
 
+        if (this._sizeChangedId)
+            this._window.disconnect(this._sizeChangedId);
+
         this._window = w;
 
         if (this._clone.source)
@@ -434,21 +437,27 @@ class CyclerHighlight extends St.Widget {
             windowActor.hide();
 
         this._clone.source = windowActor;
-    }
 
-    _onAllocationChanged() {
-        if (!this._window) {
+        if (this._window) {
+            this._onSizeChanged();
+            this._sizeChangedId = this._window.connect('size-changed',
+                this._onSizeChanged.bind(this));
+        } else {
             this._highlight.set_size(0, 0);
             this._highlight.hide();
-        } else {
-            let [x, y] = this.allocation.get_origin();
-            let rect = this._window.get_frame_rect();
-            this._highlight.set_size(rect.width, rect.height);
-            this._highlight.set_position(rect.x - x, rect.y - y);
-            this._highlight.show();
         }
     }
 
+    _onSizeChanged() {
+        const bufferRect = this._window.get_buffer_rect();
+        const rect = this._window.get_frame_rect();
+        this._highlight.set_size(rect.width, rect.height);
+        this._highlight.set_position(
+            rect.x - bufferRect.x,
+            rect.y - bufferRect.y);
+        this._highlight.show();
+    }
+
     _onDestroy() {
         this.window = null;
     }